
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>红楼梦情感分析可视化系统</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/1.6.7/axios.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Microsoft YaHei', 'SimSun', serif;
            background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
            min-height: 100vh;
            color: #333;
        }
        
        .container {
            max-width: 1400px;
            margin: 0 auto;
            padding: 20px;
        }
        
        .header {
            text-align: center;
            margin-bottom: 30px;
            background: rgba(255, 255, 255, 0.9);
            padding: 30px;
            border-radius: 15px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(10px);
        }
        
        .header h1 {
            color: #2c3e50;
            font-size: 2.5em;
            margin-bottom: 10px;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
        }
        
        .header p {
            color: #7f8c8d;
            font-size: 1.1em;
        }
        
        .controls {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-bottom: 30px;
            flex-wrap: wrap;
        }
        
        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 25px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        
        .btn-primary {
            background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        
        .btn-secondary {
            background: linear-gradient(45deg, #f093fb 0%, #f5576c 100%);
            color: white;
        }
        
        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
        }
        
        .analysis-section {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 30px;
            margin-bottom: 30px;
        }
        
        .chart-container, .table-container {
            background: rgba(255, 255, 255, 0.9);
            padding: 25px;
            border-radius: 15px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(10px);
        }
        
        .chart-title {
            font-size: 1.3em;
            font-weight: 600;
            margin-bottom: 20px;
            color: #2c3e50;
            display: flex;
            align-items: center;
            gap: 10px;
        }
        
        #sentimentChart {
            width: 100%;
            height: 400px;
        }
        
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 20px;
            margin-bottom: 30px;
        }
        
        .stat-card {
            background: rgba(255, 255, 255, 0.9);
            padding: 20px;
            border-radius: 15px;
            text-align: center;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
            backdrop-filter: blur(10px);
            transition: transform 0.3s ease;
        }
        
        .stat-card:hover {
            transform: translateY(-5px);
        }
        
        .stat-number {
            font-size: 2em;
            font-weight: bold;
            color: #667eea;
            margin-bottom: 5px;
        }
        
        .stat-label {
            color: #7f8c8d;
            font-size: 0.9em;
        }
        
        .data-table {
            width: 100%;
            border-collapse: collapse;
            margin-top: 20px;
        }
        
        .data-table th,
        .data-table td {
            padding: 12px;
            text-align: left;
            border-bottom: 1px solid #eee;
        }
        
        .data-table th {
            background: linear-gradient(45deg, #667eea 0%, #764ba2 100%);
            color: white;
            font-weight: 600;
        }
        
        .data-table tr:hover {
            background-color: rgba(102, 126, 234, 0.1);
        }
        
        .sentiment-badge {
            padding: 4px 12px;
            border-radius: 20px;
            font-size: 0.8em;
            font-weight: 500;
        }
        
        .sentiment-positive {
            background: #d4edda;
            color: #155724;
        }
        
        .sentiment-negative {
            background: #f8d7da;
            color: #721c24;
        }
        
        .sentiment-neutral {
            background: #d1ecf1;
            color: #0c5460;
        }
        
        .loading {
            text-align: center;
            padding: 40px;
            color: #7f8c8d;
        }
        
        .loading i {
            font-size: 2em;
            margin-bottom: 10px;
            animation: spin 1s linear infinite;
        }
        
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        
        .dimension-toggle {
            display: flex;
            justify-content: center;
            gap: 10px;
            margin-bottom: 20px;
        }
        
        .toggle-btn {
            padding: 8px 16px;
            border: 2px solid #667eea;
            background: transparent;
            color: #667eea;
            border-radius: 20px;
            cursor: pointer;
            transition: all 0.3s ease;
        }
        
        .toggle-btn.active {
            background: #667eea;
            color: white;
        }
        
        @media (max-width: 768px) {
            .analysis-section {
                grid-template-columns: 1fr;
            }
            
            .controls {
                flex-direction: column;
                align-items: center;
            }
            
            .header h1 {
                font-size: 2em;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1><i class="fas fa-book-open"></i> 红楼梦情感分析可视化系统</h1>
            <p>基于 SnowNLP 的情感极性分析，支持章节和人物维度展示</p>
        </div>
        
        <div class="controls">
            <button class="btn btn-primary" onclick="analyzeSample()">
                <i class="fas fa-play"></i> 分析示例文本
            </button>
            <button class="btn btn-secondary" onclick="toggleDimension()">
                <i class="fas fa-exchange-alt"></i> 切换维度
            </button>
        </div>
        
        <div class="stats-grid" id="statsGrid">
            <div class="stat-card">
                <div class="stat-number" id="totalChapters">-</div>
                <div class="stat-label">总章节数</div>
            </div>
            <div class="stat-card">
                <div class="stat-number" id="totalCharacters">-</div>
                <div class="stat-label">主要人物</div>
            </div>
            <div class="stat-card">
                <div class="stat-number" id="avgChapterSentiment">-</div>
                <div class="stat-label">章节平均情感</div>
            </div>
            <div class="stat-card">
                <div class="stat-number" id="avgCharacterSentiment">-</div>
                <div class="stat-label">人物平均情感</div>
            </div>
        </div>
        
        <div class="dimension-toggle" id="dimensionToggle" style="display: none;">
            <button class="toggle-btn active" onclick="switchToChapters()">章节分析</button>
            <button class="toggle-btn" onclick="switchToCharacters()">人物分析</button>
        </div>
        
        <div class="analysis-section">
            <div class="chart-container">
                <div class="chart-title">
                    <i class="fas fa-chart-line"></i>
                    <span id="chartTitle">情感变化趋势图</span>
                </div>
                <div id="sentimentChart"></div>
            </div>
            
            <div class="table-container">
                <div class="chart-title">
                    <i class="fas fa-table"></i>
                    <span id="tableTitle">详细数据表格</span>
                </div>
                <div id="dataTable"></div>
            </div>
        </div>
    </div>

    <script>
        let currentData = null;
        let currentDimension = 'chapters';
        let chart = null;

        // 初始化图表
        function initChart() {
            const chartDom = document.getElementById('sentimentChart');
            chart = echarts.init(chartDom);
        }

        // 分析示例文本
        async function analyzeSample() {
            showLoading();
            try {
                const response = await axios.get('/api/sample');
                currentData = response.data;
                updateStats();
                updateVisualization();
                document.getElementById('dimensionToggle').style.display = 'flex';
            } catch (error) {
                console.error('分析失败:', error);
                alert('分析失败，请检查网络连接');
            }
            hideLoading();
        }

        // 显示加载状态
        function showLoading() {
            document.getElementById('sentimentChart').innerHTML = 
                '<div class="loading"><i class="fas fa-spinner"></i><p>正在分析中...</p></div>';
            document.getElementById('dataTable').innerHTML = 
                '<div class="loading"><i class="fas fa-spinner"></i><p>正在加载数据...</p></div>';
        }

        // 隐藏加载状态
        function hideLoading() {
            // 图表和数据表格会被后续内容替换
        }

        // 更新统计信息
        function updateStats() {
            if (!currentData) return;
            
            document.getElementById('totalChapters').textContent = currentData.summary.total_chapters;
            document.getElementById('totalCharacters').textContent = currentData.summary.total_characters;
            document.getElementById('avgChapterSentiment').textContent = currentData.summary.avg_chapter_sentiment;
            document.getElementById('avgCharacterSentiment').textContent = currentData.summary.avg_character_sentiment;
        }

        // 更新可视化
        function updateVisualization() {
            if (!currentData) return;
            
            updateChart();
            updateTable();
        }

        // 更新图表
        function updateChart() {
            if (!chart) initChart();
            
            const data = currentData[currentDimension];
            const xData = data.map(item => 
                currentDimension === 'chapters' ? 
                `第${item.chapter}回` : 
                item.character
            );
            const yData = data.map(item => item.sentiment.score);
            
            const option = {
                title: {
                    text: currentDimension === 'chapters' ? '章节情感变化趋势' : '人物情感分析',
                    left: 'center',
                    textStyle: {
                        color: '#2c3e50',
                        fontSize: 16
                    }
                },
                tooltip: {
                    trigger: 'axis',
                    formatter: function(params) {
                        const item = data[params[0].dataIndex];
                        return `
                            <div style="padding: 10px;">
                                <strong>${params[0].name}</strong><br/>
                                情感得分: ${item.sentiment.score}<br/>
                                情感极性: ${item.sentiment.polarity}<br/>
                                置信度: ${item.sentiment.confidence}
                            </div>
                        `;
                    }
                },
                xAxis: {
                    type: 'category',
                    data: xData,
                    axisLabel: {
                        rotate: currentDimension === 'chapters' ? 0 : 45
                    }
                },
                yAxis: {
                    type: 'value',
                    name: '情感得分',
                    min: -1,
                    max: 1,
                    axisLabel: {
                        formatter: function(value) {
                            if (value > 0.1) return '正向';
                            if (value < -0.1) return '负向';
                            return '中性';
                        }
                    }
                },
                series: [{
                    data: yData,
                    type: 'line',
                    smooth: true,
                    lineStyle: {
                        width: 3,
                        color: '#667eea'
                    },
                    itemStyle: {
                        color: '#667eea'
                    },
                    areaStyle: {
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                            { offset: 0, color: 'rgba(102, 126, 234, 0.3)' },
                            { offset: 1, color: 'rgba(102, 126, 234, 0.1)' }
                        ])
                    }
                }],
                grid: {
                    left: '10%',
                    right: '10%',
                    bottom: '15%',
                    top: '15%'
                }
            };
            
            chart.setOption(option);
        }

        // 更新表格
        function updateTable() {
            const data = currentData[currentDimension];
            const tableTitle = currentDimension === 'chapters' ? '章节情感分析详情' : '人物情感分析详情';
            document.getElementById('tableTitle').textContent = tableTitle;
            
            let tableHTML = `
                <table class="data-table">
                    <thead>
                        <tr>
                            <th>${currentDimension === 'chapters' ? '章节' : '人物'}</th>
                            <th>情感得分</th>
                            <th>情感极性</th>
                            <th>置信度</th>
                        </tr>
                    </thead>
                    <tbody>
            `;
            
            data.forEach(item => {
                const badgeClass = item.sentiment.polarity === '正向' ? 'sentiment-positive' :
                                 item.sentiment.polarity === '负向' ? 'sentiment-negative' : 'sentiment-neutral';
                
                tableHTML += `
                    <tr>
                        <td>${currentDimension === 'chapters' ? item.title : item.character}</td>
                        <td>${item.sentiment.score}</td>
                        <td><span class="sentiment-badge ${badgeClass}">${item.sentiment.polarity}</span></td>
                        <td>${item.sentiment.confidence}</td>
                    </tr>
                `;
            });
            
            tableHTML += '</tbody></table>';
            document.getElementById('dataTable').innerHTML = tableHTML;
        }

        // 切换维度
        function toggleDimension() {
            currentDimension = currentDimension === 'chapters' ? 'characters' : 'chapters';
            updateToggleButtons();
            updateVisualization();
        }

        // 切换到章节分析
        function switchToChapters() {
            currentDimension = 'chapters';
            updateToggleButtons();
            updateVisualization();
        }

        // 切换到人物分析
        function switchToCharacters() {
            currentDimension = 'characters';
            updateToggleButtons();
            updateVisualization();
        }

        // 更新切换按钮状态
        function updateToggleButtons() {
            const buttons = document.querySelectorAll('.toggle-btn');
            buttons.forEach(btn => btn.classList.remove('active'));
            
            if (currentDimension === 'chapters') {
                buttons[0].classList.add('active');
            } else {
                buttons[1].classList.add('active');
            }
        }

        // 页面加载完成后初始化
        window.onload = function() {
            initChart();
        };

        // 窗口大小改变时重新渲染图表
        window.onresize = function() {
            if (chart) {
                chart.resize();
            }
        };
    </script>
</body>
</html>
